package com.yeskery.nut.http.servlet;

import com.yeskery.nut.core.*;
import com.yeskery.nut.http.BaseRequest;
import com.yeskery.nut.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * J2EE Servlet的Http 请求对象
 * @author sprout
 * @version 1.0
 * 2022-08-05 01:39
 */
public class ServletRequest extends BaseRequest {
    /** HttpServlet请求对象 */
    private final HttpServletRequest request;

    /**
     * 构建一个 {@link ServletRequest}
     *  @param serverContext  服务上下文
     * @param sessionManager Session 管理器
     * @param serverRequestConfiguration 服务请求配置对象
     * @param request HttpServlet请求对象
     */
    public ServletRequest(ServerContext serverContext, SessionManager sessionManager,
                          ServerRequestConfiguration serverRequestConfiguration, HttpServletRequest request) {
        super(serverContext, sessionManager, serverRequestConfiguration);
        this.request = request;

        method = Method.valueOf(request.getMethod().toUpperCase());
        path = request.getRequestURI();
        originalPath = path;
        if (!StringUtils.isEmpty(request.getQueryString())) {
            originalPath =  originalPath + "?" + request.getQueryString();
            queryParameters.putAll(getUriParameters(request.getQueryString()));
        }
        protocol = request.getProtocol();
        parameters.putAll(request.getParameterMap().entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, e -> Arrays.stream(e.getValue()).collect(Collectors.toList()))));

        headers = new HashMap<>();
        for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements();) {
            String name = e.nextElement();
            List<String> headerValues = new LinkedList<>();
            for (Enumeration<String> headerNames = request.getHeaders(name); headerNames.hasMoreElements();) {
                headerValues.add(headerNames.nextElement());
            }
            headers.put(name, headerValues);
        }

        try {
            body = readRequestBytesByInputStream(request.getInputStream());
        } catch (IOException e) {
            throw new NutException("Java Servlet InputStream IO Exception.", e);
        }
    }

    @Override
    protected byte[] readRequestBytes() {
        return new byte[0];
    }

    @Override
    public String getRemoteAddress() {
        return request.getRemoteAddr();
    }

    @Override
    public String getRemoteHost() {
        return request.getRemoteHost();
    }

    @Override
    public int getRemotePort() {
        return request.getRemotePort();
    }

    @Override
    public String getLocalAddress() {
        return request.getLocalAddr();
    }

    @Override
    public String getLocalHost() {
        return request.getLocalName();
    }

    @Override
    public int getLocalPort() {
        return request.getLocalPort();
    }
}
